package com.shanghaionstar.home.life;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;

import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.PreferencesUtls;
import com.shanghaionstar.R;
import com.shanghaionstar.utils.AlertDialogUtil;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;


/**
 * Created by Rengui Lu on 2017/1/6.
 */
public class AlarmManagerUtil {
    public static final String FIRST_SET_RENEWAL = "hasSetRenewal";
    public static final long ONE_HOUR_MILLIS = 60 * 60 * 1000;
    public static final long ONE_DAY_MILLIS = 24 * ONE_HOUR_MILLIS;
    public static final long NINE_CLOCK_MILLIS = 9 * ONE_HOUR_MILLIS;
    public static final long DAYS90_MILLIS = 89 * ONE_DAY_MILLIS;
    public static final long DAYS60_MILLIS = 59 * ONE_DAY_MILLIS;
    public static final long DAYS30_MILLIS = 29 * ONE_DAY_MILLIS;
    public static final long DAYS7_MILLIS = 6 * ONE_DAY_MILLIS;


    public static String[] renewalCategories = {IRenewalCategory.ALARM_RECEIVER_CATEGORY_TODAY, IRenewalCategory.ALARM_RECEIVER_CATEGORY_DAYS7,
            IRenewalCategory.ALARM_RECEIVER_CATEGORY_DAYS30, IRenewalCategory.ALARM_RECEIVER_CATEGORY_DAYS60};
    public static String[] assuranceCategories = {IAssuranceCategory.ALARM_RECEIVER_CATEGORY_DAYS30,
            IAssuranceCategory.ALARM_RECEIVER_CATEGORY_DAYS60, IAssuranceCategory.ALARM_RECEIVER_CATEGORY_DAYS90};

    public interface IAssuranceCategory {
        String ALARM_RECEIVER_CATEGORY_DAYS90 = "com.shanghaionstar.assurance.expiration.DAY90";
        String ALARM_RECEIVER_CATEGORY_DAYS60 = "com.shanghaionstar.assurance.expiration.DAY60";
        String ALARM_RECEIVER_CATEGORY_DAYS30 = "com.shanghaionstar.assurance.expiration.DAY30";
    }

    public interface IRenewalCategory {
        String ALARM_RECEIVER_CATEGORY_DAYS60 = "com.shanghaionstar.licence.expiration.DAYS60";
        String ALARM_RECEIVER_CATEGORY_DAYS30 = "com.shanghaionstar.licence.expiration.DAYS30";
        String ALARM_RECEIVER_CATEGORY_DAYS7 = "com.shanghaionstar.licence.expiration.DAYS7";
        String ALARM_RECEIVER_CATEGORY_TODAY = "com.shanghaionstar.licence.expiration.TODAY";
    }

    public interface IAlarmAction {
        String ALARM_RECEIVER_RENEWAL_ACTION = "com.shanghaionstar.licence.expiration";
        String ALARM_RECEIVER_COMPULSORY_ASSURANCE_ACTION = "com.shanghaionstar.compulsory.insurance.expiration";
        String ALARM_RECEIVER_BUSINESS_ASSURANCE_ACTION = "com.shanghaionstar.business.insurance.expiration";
    }


    /**
     * @param mActivity
     * @param mDateString
     * @param reminder    保险提醒
     */
    public static void showAlertDia(Context mActivity, String mDateString, String reminder) {
        long diffTime = AlarmManagerUtil.diffTime(mDateString);
        String days = diffTime / AlarmManagerUtil.ONE_DAY_MILLIS + "";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = dateFormat.parse(mDateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy年M月d日");
        String dateStr = dateFormat1.format(date);
        String reminderStr = String.format(reminder,(days !=null && days.equals("0"))?mActivity.getString(R.string.renewal_today):days, dateStr);
        AlertDialogUtil.showAlertDialog(mActivity, reminderStr);
    }

    /**
     * @param context
     * @throws ParseException 设置闹钟
     */
    public static void setRenewalAlarmManager(Context context, String mLicenceExpiration) throws ParseException {
        //每次设置前取消所有的闹钟
        cancelAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, renewalCategories);
//        String mLicenceExpiration = PreferencesUtls.getInstance(context).getString(Constants.LICENSE_EXPIRATION_DATE);
        if (TextUtils.isEmpty(mLicenceExpiration))
            return;
        long diffStamp = diffTime(mLicenceExpiration);
        if (diffStamp < 0) {
            return;
        }
        long expirationStamp = getLicenseExpirationDateStamp(mLicenceExpiration);
        //根据不同情况添加各种不同闹钟
        if (diffStamp >= DAYS60_MILLIS) {
            long timeStamp1 = expirationStamp - DAYS60_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp2 = expirationStamp - DAYS30_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp3 = expirationStamp - DAYS7_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp4 = expirationStamp + NINE_CLOCK_MILLIS;
//            long expiration = System.currentTimeMillis()+600*1000;
//            long timeStamp1 =  expiration-3*60*1000;
//            long timeStamp2 = expiration-2*60*1000;
//            long timeStamp3 = expiration-60*1000;
//            long timeStamp4 = expiration;
            long[] timeStamp = {timeStamp4, timeStamp3, timeStamp2, timeStamp1};
            executeAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, timeStamp, renewalCategories);
        } else if (diffStamp >= DAYS30_MILLIS) {
            long timeStamp1 = expirationStamp - DAYS30_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp2 = expirationStamp - DAYS7_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp3 = expirationStamp + NINE_CLOCK_MILLIS;
            long[] timeStamp = {timeStamp3, timeStamp2, timeStamp1};
            executeAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, timeStamp, renewalCategories);
        } else if (diffStamp >= DAYS7_MILLIS) {
            long timeStamp1 = expirationStamp - DAYS7_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp2 = expirationStamp + NINE_CLOCK_MILLIS;
            long[] timeStamp = {timeStamp2, timeStamp1};
            executeAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, timeStamp, renewalCategories);
        } else if (diffStamp >= ONE_DAY_MILLIS) {
            long timeStamp1 = expirationStamp + NINE_CLOCK_MILLIS;
            long[] timeStamp = {timeStamp1};
            executeAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, timeStamp, renewalCategories);
        } else {
            Date now = new Date();
            int hours = now.getHours();
            if (hours < 9) {
                long timeStamp1 = getTimesMorning() + NINE_CLOCK_MILLIS;
                long[] timeStamp = {timeStamp1};
                executeAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, timeStamp, renewalCategories);
            }
        }
    }

    /**
     * @param mActivity
     * @param mDateString 提醒换证日期和注册闹钟
     */
    public static void notifyRenewal(Context mActivity, String mDateString) {
        PreferencesUtls.getInstance(mActivity).put(Constants.LICENSE_EXPIRATION_DATE, mDateString);
        if (AlarmManagerUtil.diffTime(mDateString) < 0) {
            AlertDialogUtil.showAlertDialog(mActivity, mActivity.getString(R.string.reminder_renewal));
        } else {
            try {
                if (!PreferencesUtls.getInstance(mActivity).getBoolean(FIRST_SET_RENEWAL, false)) {
                    String reminder = mActivity.getString(R.string.reminder_driver_license);
                    showAlertDia(mActivity, mDateString, reminder);
                    PreferencesUtls.getInstance(mActivity).putBoolean(FIRST_SET_RENEWAL, true);
                }
                AlarmManagerUtil.setRenewalAlarmManager(mActivity, mDateString);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param context
     * @param sb
     * @param isBusiness 提醒保险到期和注册闹钟
     */
    public static void notifyAssuranceExpireDate(Context context, StringBuilder sb, boolean isBusiness) {
        PreferencesUtls.getInstance(context).put(isBusiness ? Constants.BUSINESS_INSURANCE_EXPIRATION_DATE : Constants.COMPULSORY_INSURANCE_EXPIRATION_DATE, sb.toString());
        long diffTime = AlarmManagerUtil.diffTime(sb.toString());
        if (diffTime < 0) {

        } else if (diffTime < AlarmManagerUtil.DAYS30_MILLIS) {
            String reminderStr = context.getResources().getString(R.string.reminder_driver_assurance_expire);
            AlertDialogUtil.showAlertDialog(context, reminderStr);
            setInsuranceAlarm(context, isBusiness, sb.toString());
        } else {
            setInsuranceAlarm(context, isBusiness, sb.toString());
        }
    }

    private static void setInsuranceAlarm(Context context, boolean isBusiness, String expireDate) {
        try {
            if (AlarmManagerUtil.diffTime(expireDate) > 0)
                AlarmManagerUtil.setInsuranceAlarmManager(context, isBusiness ? AlarmManagerUtil.IAlarmAction.ALARM_RECEIVER_BUSINESS_ASSURANCE_ACTION : AlarmManagerUtil.IAlarmAction.ALARM_RECEIVER_COMPULSORY_ASSURANCE_ACTION, expireDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param context
     * @throws ParseException 设置保险闹钟
     */
    public static void setInsuranceAlarmManager(Context context, String action, String mLicenceExpiration) throws ParseException {
        //每次设置前取消所有的闹钟
        cancelAlarmManager(context, action, assuranceCategories);
//        String mLicenceExpiration =action.equalsIgnoreCase(IAlarmAction.ALARM_RECEIVER_COMPULSORY_ASSURANCE_ACTION)?
//                PreferencesUtls.getInstance(context).getString(Constants.COMPULSORY_INSURANCE_EXPIRATION_DATE):PreferencesUtls.getInstance(context).getString(Constants.BUSINESS_INSURANCE_EXPIRATION_DATE);
        if (TextUtils.isEmpty(mLicenceExpiration))
            return;
        long diffStamp = diffTime(mLicenceExpiration);
        if (diffStamp < 0) {
            return;
        }
        long expirationStamp = getLicenseExpirationDateStamp(mLicenceExpiration);
        //根据不同情况添加各种不同闹钟
        if (diffStamp >= DAYS90_MILLIS) {

            long timeStamp1 = expirationStamp - DAYS90_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp2 = expirationStamp - DAYS60_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp3 = expirationStamp - DAYS30_MILLIS + NINE_CLOCK_MILLIS;
            long[] timeStamp = {timeStamp3, timeStamp2, timeStamp1};
            executeAlarmManager(context, action, timeStamp, assuranceCategories);
        } else if (diffStamp >= DAYS60_MILLIS) {
            long timeStamp1 = expirationStamp - DAYS60_MILLIS + NINE_CLOCK_MILLIS;
            long timeStamp2 = expirationStamp - DAYS30_MILLIS + NINE_CLOCK_MILLIS;
            long[] timeStamp = {timeStamp2, timeStamp1};
            executeAlarmManager(context, action, timeStamp, assuranceCategories);
        } else if (diffStamp >= DAYS30_MILLIS) {
            long timeStamp1 = expirationStamp - DAYS30_MILLIS + NINE_CLOCK_MILLIS;
            long[] timeStamp = {timeStamp1};
            executeAlarmManager(context, action, timeStamp, assuranceCategories);
        }
    }


    /**
     * @param context
     * @param action
     * @param categories 取消相关闹钟
     */
    public static void cancelAlarmManager(Context context, String action, String[] categories) {
        if (categories == null || categories.length == 0)
            return;
        for (String category : categories) {
            cancelAlarmManager(context, category, action);
        }
    }

    public static void cancelAllAlram(Context context) {
        cancelAlarmManager(context, IAlarmAction.ALARM_RECEIVER_RENEWAL_ACTION, renewalCategories);
        cancelAlarmManager(context, IAlarmAction.ALARM_RECEIVER_COMPULSORY_ASSURANCE_ACTION, assuranceCategories);
        cancelAlarmManager(context, IAlarmAction.ALARM_RECEIVER_BUSINESS_ASSURANCE_ACTION, assuranceCategories);
    }

    /**
     * @param context
     * @param type
     * @param action  取消单个闹钟
     */
    public static void cancelAlarmManager(Context context, String type, String action) {
        Intent intent = new Intent(context, AlarmReceiver.class);
        intent.setAction(action);
        intent.addCategory(type);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        am.cancel(pendingIntent);
    }


    /**
     * @param expirationDate
     * @return 计算时间差，单位为毫秒
     */
    public static long diffTime(String expirationDate) {
        long licenseExpirationDateStamp = getLicenseExpirationDateStamp(expirationDate);
        long curStamp = getTimesMorning();
        long diffStamp = licenseExpirationDateStamp - curStamp;
        return diffStamp;
    }

    /**
     * @param expirationDate
     * @return 根据字符串获取时间戳
     */
    private static long getLicenseExpirationDateStamp(String expirationDate) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = df.parse(expirationDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        cal.setTime(date);
        return cal.getTimeInMillis();
    }

    /**
     * @return 获取当天00:00:00的时间戳
     */
    public static long getTimesMorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTimeInMillis();
    }


    /**
     * @param context
     * @param action
     * @param timeStamp
     * @param categories 添加一组闹钟
     */
    public static void executeAlarmManager(Context context, String action, long[] timeStamp, String[] categories) {
        if (timeStamp == null || categories == null || context == null)
            return;
        int len = timeStamp.length;
        long curStamp = System.currentTimeMillis();
        for (int i = 0; i < len; i++) {
            if (timeStamp[i] < curStamp)
                continue;
            executeAlarmManager(context, action, timeStamp[i], categories[i]);
        }
    }

    /**
     * @param context
     * @param action
     * @param timeStamp
     * @param category  添加一个闹钟
     */
    public static void executeAlarmManager(Context context, String action, long timeStamp, String category) {
        Intent intent = new Intent(context, AlarmReceiver.class);
        intent.setAction(action);
        intent.addCategory(category);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        am.set(AlarmManager.RTC_WAKEUP, timeStamp, pendingIntent);
    }

}
